Ask The Oracle
[crypto]
Ask The Oracle
Mr Robot has worked all night to find the Cipher "TIe8CkeWpqPFBmFcIqZG0JoGqBIWZ9dHbDqqfdx2hPlqHvwH/+tbAXDSyzyrn1Wf" then he faints of Overdose.You are left with a challenge to get the key to the database before EVIL CORP starts backing up the data.
- URL: ctf.pragyan.org 8500
Recon
The server asks for a ciphertext and IV. After that the server just spits out the actual IV used for the given ciphertext. The server will tell you if the padding is wrong of the decrypted ciphertext that we can provide. It is therefore vulnerable to a padding oracle attack.
Code
import pwn
from base64 import b64encode, b64decode
pwn.context.log_level = pwn.logging.ERROR
cipher = "TIe8CkeWpqPFBmFcIqZG0JoGqBIWZ9dHbDqqfdx2hPlqHvwH/+tbAXDSyzyrn1Wf"
cipherb = b64decode(cipher)
iv = "VGhpcyBpcyBhbiBJVjQ1Ng=="
ivb = b64decode(iv)
allb = ivb + cipherb
def send(cipher, iv):
conn = pwn.remote('ctf.pragyan.org', 8500)
conn.recvuntil('Enter in format \'<Ciphertext>|<Initialisation Vector>\'\n')
conn.send(f'{cipher}|{iv}\n'.encode())
conn.recvuntil('VGhpcyBpcyBhbiBJVjQ1Ng==\n')
res = conn.recv()
conn.close()
return b'Cipher Error!\n' in res
plain = []
for block in range(len(allb), 16, -16):
pad = []
c2 = b64encode(bytearray(allb[block - 16:block])).decode()
for byte in range(1, 17):
c1b = allb[block - 16 - byte]
c1 = (16 - byte) * [0xf0] + [0] + [p ^ byte for p in pad]
for i in range(0, 256):
if c1b ^ (i ^ byte) > 126:
continue
c1[-byte] = i
if send(c2, b64encode(bytes(c1)).decode()):
pad.insert(0, i ^ byte)
plain.insert(0, c1b ^ (i ^ byte))
break
print(plain)
print(''.join([chr(p) for p in plain]))
Flag
pctf{b@d_p@nd@s_@r3_3v3rywh3r3_c@tch}